#!/usr/bin/env python
# Create: 2018/12/17
__author__ = '749B'

import logging
import re
from string import Template

from log_audit import models

logger = logging.getLogger(__name__)


# 字符串模板
TEMPLE_RE = {
    'ip_addr': "((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))",
    'port': "([1-9]|\d{2,4}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])",
    'ip_port': "((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))"
               ":\s?"
               "([1-9]|\d{2,4}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])",
}


def auto_tag(o):
    """入口函数
    o： 字典 {'first_log': obj, 'last_log': obj, 'count': 1}
    """
    # count, message, key 是最基本的需要判断的字段。先提取出来处理好
    # o, q 两个对象依然进行传递，应该不会有什么效率问题，方便以后匹配更加复杂的逻辑可能会用到
    count, message = o.get('count'), o.get('last_log').message.strip()
    qs = models.AutoAuditRule.objects.order_by('-count')  # 按count降序排序，同样的key先匹配到count高的，然后直接返回
    for q in qs.values('type', 'key', 'count', 'auto_tag'):
        key = q['key'].strip()
        if q['type'] == 1:
            tag = str_match(o, q, count, message, key)
        elif q['type'] == 2:
            tag = str_search(o, q, count, message, key)
        elif q['type'] == 3:
            tag = re_search(o, q, count, message, key)
        elif q['type'] == 4:
            tag = re_template(o, q, count, message, key)
        else:
            continue
        if tag:
            return tag


def str_match(o, q, count, message, key):
    if message == key and count >= q['count']:
        logger.debug("str_match %s %s" % (q['auto_tag'], key))
        return q['auto_tag']


def str_search(o, q, count, message, key):
    if key in message and count >= q['count']:
        logger.debug("str_search %s %s in %s" % (q['auto_tag'], key, message))
        return q['auto_tag']


def re_search(o, q, count, message, key):
    re_res = re.search(key, message)
    if re_res:
        if count >= q['count']:
            logger.debug("re_search %s %s" % (q['auto_tag'], re_res.group()))
            return q['auto_tag']


def re_template(o, q, count, message, key):
    s = Template(key).safe_substitute(**TEMPLE_RE)
    re_res = re.search(s, message)
    if re_res:
        if count >= q['count']:
            logger.debug("re_template %s %s" % (q['auto_tag'], re_res.group()))
            return q['auto_tag']

